<template>
  <div class="my-table-container"
       @mouseenter="mouseenter = true"
       @mouseleave="mouseenter = false"
       @mousewheel="onMouseWheel($event)">
    <table class="my-table-head">
      <thead>
      <tr>
        <th v-if="!(col.customData)" v-for="(col,index) in columns" :key="index" :style="col.style"
            @click="sort(col.field)"><span class="th-header">{{ col.name }}</span><span class="iconfont"
                                                                                        :class="[!currentSortedField?'icon-biaotou-kepaixu':col.field===currentSortedField?(!sortType?'icon-paixu-shang':'icon-paixu-xia'):'']"
                                                                                        ref="icon"></span></th>
      </tr>
      </thead>
    </table>
    <div class="my-table-body-container">
      <table
          class="my-table-body"
          :style="{top:top+'px'}"
          ref="tableContent"
      >
        <tbody>
        <tr v-for="(item,rowIndex) in rows" :key="rowIndex" @click="rowClick(item,rowIndex)">
          <td
              v-for="(value,key,colIndex) in item"
              :style="heads(columns,colIndex,item).col.style"
              :class="{active:heads(columns,colIndex,item).col.field===currentSortedField}"
              v-if="!heads(columns,colIndex,item).col.customData&&!useindex"
              :key="value+key+colIndex"
          >
            <slot :name="colIndex"
                  :info="{item:item,value:heads(columns,colIndex,item).value,rowIndex:rowIndex,colIndex:colIndex}"><div v-html="heads(columns, colIndex, item).value"></div></slot>
          </td>
          <td
              v-for="(value,key,colIndex) in item"
              v-if="(!(columns[colIndex].customData||false))&&useindex"
              :key="rowIndex+key+columns[colIndex]"
              :style="columns[colIndex].style"
              @click="columns[colIndex].onClick && columns[colIndex].onClick(item,value,rowIndex,colIndex)"
              :class="{active:columns[colIndex].field===currentSortedField}"
          >
            <slot :name="colIndex"
                  :info="{item:item,value:value,rowIndex:rowIndex,colIndex:colIndex}"><div v-html="value"></div></slot>
          </td>
        </tr>
        </tbody>
      </table>
    </div>
  </div>
</template>
<script>

export default {
  name: 'DataGrid',
  props: {
    columns: {
      type: Array,
      default: function () {
        return []
      }
    },
    rows: {
      type: Array,
      default: function () {
        return []
      }
    },
    slide: {
      type: Boolean,
      default: function () {
        return false
      }
    },
    duration: {
      type: Number,
      default: function () {
        return 2000
      }
    },
    useindex: {
      type: Boolean,
      default: function () {
        return true
      }
    }
  },
  components: {},
  computed: {
    heads: function () {
      return function (columns, colIndex, item) {
        var col = columns[colIndex]
        var value = item[col.field]
        return {
          col: col,
          value: value
        }
      }
    }
  },
  data() {
    return {
      top: 0,
      timer: null,
      onShowElementIndex: 0,
      // true 升序 false 降序
      sortType: true,
      currentSortedField: null,
      mouseenter: false
    }
  },
  methods: {
    slideAndShow: function () {
      if (this.onShowElementIndex >= this.rows.length - 0) {
        this.resetTop();
      } else {
        this.slideDown();
      }
    },
    runSlideDuration: function (mouseenter) {
      if (this.slide && !(mouseenter || this.mouseenter)) {
        if (!this.timer) {
          this.timer = setInterval(this.slideAndShow, this.duration)
        }
      } else {
        if (this.timer) {
          clearInterval(this.timer)
          this.timer = null
        }
      }
    },
    onMouseWheel: function (event) {
      if (event.wheelDeltaY > 0) {
        // 向上滚动中键
        this.slideUp()
      } else {
        // 向下滚动中键
        this.slideDown()
      }
    },
    slideUp: function () {
      if (this.onShowElementIndex >= 0) {
        if (this.$refs.tableContent === undefined) {

        } else {
          const tr = this.$refs.tableContent.querySelector(
              `tr:nth-child(${this.onShowElementIndex - 1})`
          )
          if (tr) {
            this.onShowElementIndex--
            this.top = tr.offsetTop * -1
          }
        }
      }
    },
    slideDown: function () {
      if (this.onShowElementIndex <= this.rows.length - 0) {
        if (this.$refs.tableContent === undefined) {

        } else {
          const tr = this.$refs.tableContent.querySelector(
              `tr:nth-child(${this.onShowElementIndex + 1})`
          )
          if (tr) {
            this.onShowElementIndex++
            this.top = tr.offsetTop * -1
          }
        }
      }
    },
    sort: function (field) {
      if (this.sortType) {
        this.rows = this.rows.sort((a, b) => {
          if (typeof (a[field]) === 'number' && typeof (b[field]) === 'number') {
            return a[field] - b[field]
          } else if (typeof (a[field]) === 'string' && typeof (b[field]) === 'string') {
            return String(a[field]).localeCompare(String(b[field]))
          } else if (a[field] == null || b[field] == null) {
            return -1;
          }
        })
      } else {
        this.rows = this.rows.sort((a, b) => {
          if (typeof (a[field]) === 'number' && typeof (b[field]) === 'number') {
            return b[field] - a[field]
          } else if (typeof (a[field]) === 'string' && typeof (b[field]) === 'string') {
            return String(b[field]).localeCompare(String(a[field]))
          } else if (a[field] == null || b[field] == null) {
            return -1;
          }
        })
      }
      this.sortType = !this.sortType;
      this.currentSortedField = field;
    },
    rowClick: function (item, index) {
      this.$emit('row-clicked', item, index);
    },
    addFontStyleLink: function (url) {
      var link = document.createElement("link");
      link.type = "text/css";
      link.rel = "stylesheet";
      link.href = url;
      var head = document.head;
      head.appendChild(link);
    },
    getContextPath() {
      if (location.pathname.indexOf('/') !== -1) {
        return '/' + location.pathname.split('/')[1]
      } else {
        return '/'
      }
    },
    cutSortIcon: function () {
      var icons = document.querySelectorAll('span.th-header:empty + span.iconfont');
      for (var i = 0; i < icons.length; i++) {
        icons[i].parentNode.removeChild(icons[i])
      }
    },
    resetTop() {
      this.top = 0;
      this.onShowElementIndex = 0;
    }
  },
  watch: {
    rows: function (newValue, oldValue) {
      if (newValue.length > 0) {
        !this.mouseenter && this.runSlideDuration()
      }
      this.resetTop();
    },
    mouseenter: function (newValue, oldValue) {
      this.runSlideDuration(newValue)
    }
  },
  beforeCreate: function () {
  },
  created: function () {
    // this.addFontStyleLink(this.getContextPath() + '/screen/components/datagrid/fonts/iconfont.css')
    this.runSlideDuration()
  },
  mounted: function () {
    this.cutSortIcon()
  }
}
</script>

<style scoped>
@import "./datagrid.css";
@import "./themes/wide-row.css";
@import "./fonts/iconfont.css";
</style>

